package com.fingard.dsp.bank.directbank.czb01;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.util.*;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.net.WebRequest;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.codec.binary.Hex;
import sun.misc.BASE64Decoder;

/**
 * Created by Fish on 2017/11/13.
 */
public class CZB01Base extends DirectBase implements ITcpClient {

    protected List<RetAtsTransDetail> retRetailList = new ArrayList();


    //解析200112接口返回报文
    private Map<String, String> parseRespMsg_200112(String[] retStrArr, RetAtsTrans retAts, String actArea) throws Exception {
        Map<String, String> resultMap = new HashMap();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        int curRecordNum = 0;//记录数
        int totalRecordNum = 0;//总记录数
        String totalfilename = "";//总结果文件名
        if (retStrArr[0].length() == 0) {
            StringBuilder curSbMsg = new StringBuilder();
            XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
            if (curBkReader != null) {
                String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                String curDataMFS = "";
                if ("0000".equals(curRetCode)) {
                    curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                    totalRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/total_record_num"));
                    totalfilename = curBkReader.getFirstText("/ap/body/totalfilename");
                    int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                    if (curRecordNum > 0) {
                        String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                        if ("1".equals(curFileFlag)) {
                            String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                            String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                            if (StringHelper.hasAnyChar(curFilePath)) {
                                WriteBankLogLn("读取前置数据文件：" + curFilePath);
                                curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                                WriteBankLogStep3(curDataMFS);
                            } else {
                                WriteBankLogLn("前置数据文件【" + curFilePath + "】不存在");
                            }
                        } else {
                            curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (StringHelper.hasAnyChar(curDataMFS)) {
                            StringBuilder curSbLog = new StringBuilder();
                            ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                            if (curSbLog.length() == 0) {
                                //region **字段映射表
                                /*
                                  0银行流水号（C20）| 1交易渠道（C2）| 2交易类型（C8）| 3账号（40）| 4户名（80）| 5开户行号（12）|
                                  6开户行名（C150）| 7对方账号（C40）| 8对方户名(C100)| 9对方开户行号（C12）| 10对方开户行名（C100）|
                                  11币种(C2)| 12交易金额N(16.2)| 13交易日期（C8）| 14交易时间（C6）| 15回单打印次数（N4）|16摘要（C10）|
                                  17防伪码（C50）|18用途（C100）|19附言（C100）|20备注（C100）|21备用（C100）|22余额|23回单详细信息(BASE64)（不用）|
                                */
                                /*回单详细信息(BASE64)(暂时不用)
                                业务类型：外汇汇入汇款| 报单号：7| 渠道：SWIFT| 原始汇款金额：人民币7821.00| 手续费金额：人民币100.00|
                                邮电费金额：人民币50.00| 子账号：123456| 汇款行业务编号：CDI1222.| 收款人名称：dcddff| 汇款人地址：民心路100号|
                                汇款附言：/INS/SZDBCNBS/INS/SCBLUS33///CHPREF/0044704|
                                汇款详情：/RFB/OREO02511602371OSA PAYMENT PAYER IS OFFSHORE CUSTREG. GBR CONT.NO.. 31567-15INV.NO.. 31567-15 PAYMENT FOR GOODS|
                                发起柜员：99999| 业务受理编号：999991701190028| 交易时间：2017-01-19 08:51:10
                                 */
                                //endregion
                                for (int i = 1; i < curDataList.size(); i++) {
                                    String[] curRowDataArr = curDataList.get(i);
                                    RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();

                                    tmpRetDetail.actArea = actArea;//账号区域编码
                                    tmpRetDetail.actNum = curRowDataArr[3].trim();//账号
                                    tmpRetDetail.recAccNum = curRowDataArr[7].trim();//收款账号
                                    tmpRetDetail.recAccName = curRowDataArr[8].trim();//收款名
                                    tmpRetDetail.recAccBank = StringHelper.convertToDBC(curRowDataArr[10]).trim();//收款开户行
                                    //交易日期
                                    tmpRetDetail.tranDate = curRowDataArr[13].substring(0, 4)
                                            + "-" + curRowDataArr[13].substring(4, 6) + "-" + curRowDataArr[13].substring(6, 8);
                                    //交易时间
                                    tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " +
                                            curRowDataArr[14].substring(0, 2) + ":" + curRowDataArr[14].substring(2, 4) + ":" + curRowDataArr[14].substring(4, 6);
                                    //起息日期
                                    tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                    tmpRetDetail.cdFlag = curRowDataArr[2]; // 交易类型 ：1 借（付款） 2 贷 （收款）
                                    tmpRetDetail.tranAmt = curRowDataArr[12];//交易金额
                                    tmpRetDetail.accBal = curRowDataArr[22];//账户余额
                                    tmpRetDetail.comment = StringHelper.joinNotEmpty(";", curRowDataArr[19], curRowDataArr[20]);//备注
                                    tmpRetDetail.cur = this.convertCurToATS(curRowDataArr[11]);//币种
                                    tmpRetDetail.originator = curRowDataArr[0].trim();//银行返回流水号
//                                    tmpRetDetail.busType = curRowDataArr[1];//业务类型

                                    retRetailList.add(tmpRetDetail);
                                    nodeAnalysic(curRowDataArr, tmpRetDetail, getCharset());
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = curSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "0";
                            tmpRespInfo = "明细为空";
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = curRetInfo;
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = curSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = retStrArr[1];
        }
        resultMap.put("tmpRespCode", tmpRespCode);
        resultMap.put("tmpRespInfo", tmpRespInfo);
        resultMap.put("totalRecordNum", totalRecordNum + "");
        resultMap.put("recordNum", curRecordNum + "");
        resultMap.put("totalfilename", totalfilename);
        return resultMap;
    }

    //解析200112接口返回报文 含回单信息
    private Map<String, String> parseRespMsg_200112(String[] retStrArr, RetAtsTrans retAts, String actArea, String actCur) throws Exception {
        Map<String, String> resultMap = new HashMap();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        int curRecordNum = 0;//记录数
        int totalRecordNum = 0;//总记录数
        String totalfilename = "";//总结果文件名
        if (retStrArr[0].length() == 0) {
            StringBuilder curSbMsg = new StringBuilder();
            XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
            if (curBkReader != null) {
                String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                String curDataMFS = "";
                if ("0000".equals(curRetCode)) {
                    curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                    totalRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/total_record_num"));
                    totalfilename = curBkReader.getFirstText("/ap/body/totalfilename");
                    int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                    if (curRecordNum > 0) {
                        String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                        if ("1".equals(curFileFlag)) {
                            String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                            String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                            if (FileHelper.existFile(curFilePath)) {
                                WriteBankLogLn("读取前置数据文件：" + curFilePath);
                                curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                                WriteBankLogStep3(curDataMFS);
                            } else {
                                WriteBankLogLn("前置数据文件【" + curFilePath + "】不存在");
                            }
                        } else {
                            curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (StringHelper.hasAnyChar(curDataMFS)) {
                            StringBuilder curSbLog = new StringBuilder();
                            ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                            if (curSbLog.length() == 0) {
                                //region **字段映射表
                                /*
                                  0银行流水号（C20）| 1交易渠道（C2）| 2交易类型（C8）| 3账号（40）| 4户名（80）| 5开户行号（12）|
                                  6开户行名（C150）| 7对方账号（C40）| 8对方户名(C100)| 9对方开户行号（C12）| 10对方开户行名（C100）|
                                  11币种(C2)| 12交易金额N(16.2)| 13交易日期（C8）| 14交易时间（C6）| 15回单打印次数（N4）|16摘要（C10）|
                                  17防伪码（C50）|18用途（C100）|19附言（C100）|20备注（C100）|21备用（C100）|22余额|23回单详细信息(BASE64)（不用）|
                                */
                                /*回单详细信息(BASE64)(暂时不用)
                                业务类型：外汇汇入汇款| 报单号：7| 渠道：SWIFT| 原始汇款金额：人民币7821.00| 手续费金额：人民币100.00|
                                邮电费金额：人民币50.00| 子账号：123456| 汇款行业务编号：CDI1222.| 收款人名称：dcddff| 汇款人地址：民心路100号|
                                汇款附言：/INS/SZDBCNBS/INS/SCBLUS33///CHPREF/0044704|
                                汇款详情：/RFB/OREO02511602371OSA PAYMENT PAYER IS OFFSHORE CUSTREG. GBR CONT.NO.. 31567-15INV.NO.. 31567-15 PAYMENT FOR GOODS|
                                发起柜员：99999| 业务受理编号：999991701190028| 交易时间：2017-01-19 08:51:10
                                 */
                                //endregion
                                for (int i = 1; i < curDataList.size(); i++) {
                                    String[] curRowDataArr = curDataList.get(i);
                                    RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();

                                    // zzy ATSES-24250 回单信息的获取
                                    String mactacn = "";// 被代理账号
                                    String mactname = "";// 被代理账户名
                                    String receiptStrBef = curRowDataArr[23].trim();// base64的回单信息
                                    BASE64Decoder decoder = new BASE64Decoder();
                                    byte[] bytes = decoder.decodeBuffer(receiptStrBef);
                                    String receiptStrAft = new String(bytes, getCharset());
//                                    String receiptStrAft = Base64.decode(receiptStrBef);// 解密后的回单信息  有四种类型
                                    StringBuilder tmpSbLog = new StringBuilder();
                                    ArrayList<String[]> receiptList = new ArrayList<String[]>();
                                    // 区分为第四种类型回单
                                    int i1;
                                    int i2 = receiptStrAft.indexOf("|");
                                    if (receiptStrAft.contains("业务种类")) {
                                        i1 = receiptStrAft.indexOf("业务种类");
                                    } else if (receiptStrAft.contains("业务渠道")) {
                                        i1 = receiptStrAft.indexOf("业务渠道");
                                    } else if (receiptStrAft.contains("业务类型")) {
                                        i1 = receiptStrAft.indexOf("业务类型");
                                    } else {
                                        throw new RuntimeException("回单明细中不支持的类型");
                                    }
                                    String kind = receiptStrAft.substring(i1, i2);
                                    if ("业务类型：外汇汇入汇款".equals(kind)) {
                                        // 类型1、2、3
                                        String cur = receiptStrAft.substring(receiptStrAft.indexOf("原始汇款金额"), receiptStrAft.indexOf("原始汇款金额") + 12);
                                        if (cur.contains("人民币")) {
                                            // 类型3 跨境人民币入账（SWIFT渠道）
                                            receiptList = MFSHelper.getTextArray(curDataMFS, "|", 15, 1, tmpSbLog);
                                            if (tmpSbLog.length() == 0) {
                                                String[] rowDataArr = receiptList.get(1);
                                                mactacn = rowDataArr[6].trim().split(":")[1];
                                                mactname = rowDataArr[8].trim().split(":")[1];
                                            }
                                        } else if (!"01".equals(actCur)) {
                                            // 类型2 外币入账（适用于在本行开立外币结算账户）
                                            receiptList = MFSHelper.getTextArray(curDataMFS, "|", 16, 1, tmpSbLog);
                                            if (tmpSbLog.length() == 0) {
                                                String[] rowDataArr = receiptList.get(1);
                                                mactacn = rowDataArr[7].trim().split(":")[1];
                                                mactname = rowDataArr[9].trim().split(":")[1];
                                            }
                                        } else {
                                            // 类型1 外币结汇入账（适用于在本行没有开立外币结算账户）(510003交易)
                                            receiptList = MFSHelper.getTextArray(curDataMFS, "|", 17, 1, tmpSbLog);
                                            if (tmpSbLog.length() == 0) {
                                                String[] rowDataArr = receiptList.get(1);
                                                mactacn = rowDataArr[8].trim().split(":")[1];
                                                mactname = rowDataArr[10].trim().split(":")[1];
                                            }
                                        }
                                    } else {
                                        // 类型4 跨境人民币入账（大额支付系统）
                                        receiptList = MFSHelper.getTextArray(curDataMFS, "|", 13, 1, tmpSbLog);
                                        if (tmpSbLog.length() == 0) {
                                            String[] rowDataArr = receiptList.get(1);
                                            mactacn = rowDataArr[5].trim().split(":")[1];
                                            mactname = rowDataArr[8].trim().split(":")[1];
                                        }
                                    }
                                    tmpRetDetail.mactacn = mactacn;// 被代理账号
                                    tmpRetDetail.mactname = mactname;// 被代理账户名

                                    tmpRetDetail.actArea = actArea;//账号区域编码
                                    tmpRetDetail.actNum = curRowDataArr[3].trim();//账号
                                    tmpRetDetail.recAccNum = curRowDataArr[7].trim();//收款账号
                                    tmpRetDetail.recAccName = curRowDataArr[8].trim();//收款名
                                    tmpRetDetail.recAccBank = StringHelper.convertToDBC(curRowDataArr[10]).trim();//收款开户行
                                    //交易日期
                                    tmpRetDetail.tranDate = curRowDataArr[13].substring(0, 4)
                                            + "-" + curRowDataArr[13].substring(4, 6) + "-" + curRowDataArr[13].substring(6, 8);
                                    //交易时间
                                    tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " +
                                            curRowDataArr[14].substring(0, 2) + ":" + curRowDataArr[14].substring(2, 4) + ":" + curRowDataArr[14].substring(4, 6);
                                    //起息日期
                                    tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                    tmpRetDetail.cdFlag = curRowDataArr[2]; // 交易类型 ：1 借（付款） 2 贷 （收款）
                                    tmpRetDetail.tranAmt = curRowDataArr[12];//交易金额
                                    tmpRetDetail.accBal = curRowDataArr[22];//账户余额
                                    // ATSES-22232 通威目前在用的十个支付渠道,对账码识别截取优化 -----范天星/2020/0/16
//                                    String purpose = curRowDataArr[18];
//                                    if (purpose.contains("＋")) {
//                                        tmpRetDetail.abstr = purpose.split("＋")[1];
//                                        tmpRetDetail.usage = purpose.split("＋")[0];
//                                    } else {
//                                        tmpRetDetail.abstr = "";
//                                        tmpRetDetail.usage = purpose;
//                                    }
                                    tmpRetDetail.comment = StringHelper.joinNotEmpty(";", curRowDataArr[19], curRowDataArr[20]);//备注
                                    tmpRetDetail.cur = this.convertCurToATS(curRowDataArr[11]);//币种
                                    tmpRetDetail.originator = curRowDataArr[0].trim();//银行返回流水号
                                    tmpRetDetail.base64Str = curRowDataArr[23];//回单详细信息(BASE64)
//                                    tmpRetDetail.busType = curRowDataArr[1];//业务类型

                                    nodeAnalysic(curRowDataArr, tmpRetDetail, getCharset());
                                    retRetailList.add(tmpRetDetail);
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = curSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "0";
                            tmpRespInfo = "明细为空";
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = curRetInfo;
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = curSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = retStrArr[1];
        }
        resultMap.put("tmpRespCode", tmpRespCode);
        resultMap.put("tmpRespInfo", tmpRespInfo);
        resultMap.put("totalRecordNum", totalRecordNum + "");
        resultMap.put("recordNum", curRecordNum + "");
        resultMap.put("totalfilename", totalfilename);
        return resultMap;
    }

    //历史交易明细查询调用200112接口
    protected RetAtsTrans hisTrans_200112(Req7516HisTrans p_req7516) throws Exception {
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        retAts.writeStart();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        try {
            //region 一：参数定义
            Calendar qryFromCldar = Calendar.getInstance();        //记录整个查询开始日期的日历
            Calendar qryToCldar = Calendar.getInstance();          //记录整个查询截止日期的日历
            Calendar curQryFrom = Calendar.getInstance();          //本次分月查询开始日期（日历）
            Calendar curQryTo = Calendar.getInstance();            //本次分月查询结算日期（日历）
            //endregion

            //region 二：参数值初始化
            qryFromCldar.setTime(p_req7516.getDateFrom());      //设置整个查询开始日期
            qryToCldar.setTime(p_req7516.getDateTo());          //设置整个查询截止日期
            curQryFrom.setTime(qryFromCldar.getTime());         //设置本次查询开始日期
            //endregion

            //region 三：按自然月，分月（页）查询
            while (curQryFrom.compareTo(qryToCldar) <= 0 && tmpRespCode.length() == 0) {

                //region【1】计算本次查询截止日期
                if (DateHelper.compareMonth(curQryFrom, qryToCldar) == -1) {
                    //开始日期 与 截止日期 为 跨月关系时，查本月信息
                    curQryTo.setTime(curQryFrom.getTime());
                    curQryTo.set(Calendar.DAY_OF_MONTH, curQryTo.getActualMaximum(Calendar.DAY_OF_MONTH));
                } else {
                    //开始日期 与 截止日期 为 同月关系时，查全部信息
                    curQryTo.setTime(qryToCldar.getTime());
                }
                //endregion
                //===========================================================

                //每个月次查询得到得数据，按分页查询得到数据，每页/10条，如果总的数据条数超过10条要再次发起查询page页+1
                //页码初始为1
                int pageno = 1;//页码
                int recordNum = 0;//记录数
                int totalRecordNum = 0;//总记录数
                boolean isAgain = false;
                String totalfilename = "";//总体结果文件名称
                do {
                    //region【2】组装查询报文
                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    CZB01Header bankHeader = new CZB01Header();
                    bankHeader.transCode = "200112";//交易代码
                    bankHeader.reqSeqNo = p_req7516.reqHeader.transSeqID;

                    writeCommonHeader(xmlWriter, bankHeader);
                    xmlWriter.writeStartElement("body");
                    xmlWriter.writeElementString("acno", p_req7516.actNum);
                    xmlWriter.writeElementString("cur_code", convertCurToBank(p_req7516.actCur));
                    xmlWriter.writeElementString("start_date", Format.Date8Format.format(curQryFrom.getTime()));
                    xmlWriter.writeElementString("end_date", Format.Date8Format.format(curQryTo.getTime()));
                    xmlWriter.writeElementString("pageno", pageno + "");//页码
                    xmlWriter.writeElementString("totalfilename", pageno == 1 ? "" : totalfilename, true);//结果文件名称，当页码为2或者2以上时，该字段必输
                    xmlWriter.writeElementString("isbal", "1");//1表示需要余额。不填或0表示不需要余额字段
                    xmlWriter.writeElementString("isReceipt", getBankConfig().getValueAsString("hasReceiptInfo"));//是否需要回单详细信息，1 表示需要。不填或者0表示不需要
                    xmlWriter.writeElementClosed("isBailAccount");//是否为查询保证金账户明细，1 表示需要。不填或者0表示不需要
                    xmlWriter.writeElementClosed("poolStatus");//资产池开通状态，查询保证金账户明细时必输时 0已开通；1暂停；9关闭
                    xmlWriter.writeEndElement();//body
                    xmlWriter.writeEndElement();//ap
                    xmlWriter.writeEndDocument();
                    //endregion

                    //region【3】发送请求报文
                    String[] retStrArr = sendToBank(xmlWriter.toXmlString());
//                    String[] retStrArr = new String[]{"","<ap><head><tr_code>200112</tr_code><cms_corp_no></cms_corp_no><user_no></user_no><req_no>1238536714</req_no><serial_no>13174018</serial_no><tr_acdt>20200430</tr_acdt><tr_time>124122</tr_time><succ_flag>0</succ_flag><ret_info>交易成功</ret_info><ret_code>0000</ret_code><ext_info></ext_info><reserved></reserved><file_flag>1</file_flag><org_code></org_code></head><body><totalfilename>TSYQ2020043013174018_tmp</totalfilename><record_num>1</record_num><total_record_num>1</total_record_num><field_num>23</field_num><file_name>2020043013174017</file_name></body></ap>"};

                    //endregion

                    //region【4】解析响应报文
                    Map<String, String> parseResultMap = new HashMap<String, String>();
                    // 判断是否需要回单信息 zzy
                    String flag = getBankConfig().getValueAsString("TransGetReceipt");
                    if ("true".equals(flag)) {
                        //20200514--ATSES-24250还在测试ftx
//                        parseResultMap = parseRespMsg_200112(retStrArr, retAts, p_req7516.actArea, p_req7516.actCur);
                    } else {
                        parseResultMap = parseRespMsg_200112(retStrArr, retAts, p_req7516.actArea);
                    }

                    tmpRespCode = parseResultMap.get("tmpRespCode");
                    tmpRespInfo = parseResultMap.get("tmpRespInfo");
                    recordNum = Integer.parseInt(parseResultMap.get("recordNum"));
                    totalRecordNum = Integer.parseInt(parseResultMap.get("totalRecordNum"));
                    totalfilename = parseResultMap.get("totalfilename");
                    //endregion

                    if (totalRecordNum != recordNum + (pageno - 1) * 10 && tmpRespCode.length() == 0) {
                        pageno++;
                        isAgain = true;
                    } else {
                        isAgain = false;
                    }
                } while (isAgain);//判断是否当(页码pageno-1)*10+record_num=total_record_num时，表示没有下一页，无需再次进行查询；否则需要进行下一次查询。


                //=============================================
                //region 【5】增加月数，继续查询
                curQryFrom.setTime(curQryTo.getTime());
                curQryFrom.add(Calendar.DAY_OF_MONTH, 1);
                //endregion
            }
            //endregion
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if ("-1".equals(tmpRespCode)) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespInfo(tmpRespInfo);
            retAts.writeRespCode(tmpRespCode);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter, CZB01Header czb01Header) throws Exception {
        xmlWriter.writeStartDocument();
        xmlWriter.writeStartElement("ap");
        xmlWriter.writeStartElement("head");
        xmlWriter.writeElementString("tr_code", czb01Header.transCode);                                 //交易码
        xmlWriter.writeElementClosed("cms_corp_no");                                                     //银企客户号
        xmlWriter.writeElementClosed("user_no");                                                         //用户号
        xmlWriter.writeElementClosed("org_code");                                                        //机构号
        xmlWriter.writeElementClosed("serial_no");                                                       //交易流水号
        xmlWriter.writeElementString("req_no", czb01Header.reqSeqNo);
        if (czb01Header.reqDateTime == null) {
            czb01Header.reqDateTime = new Date();
        }
        xmlWriter.writeElementString("tr_acdt", Format.Date8Format.format(czb01Header.reqDateTime));  //交易日期
        xmlWriter.writeElementString("tr_time", Format.Time6Format.format(czb01Header.reqDateTime));  //交易时间
        xmlWriter.writeElementString("channel", "5");                                          //渠道标识
        xmlWriter.writeElementString("sign", "0");                                              //签名标识
        xmlWriter.writeElementString("file_flag", "0");                                        //文件标识
        xmlWriter.writeElementClosed("reserved");                                                        //保留字段
        xmlWriter.writeEndElement();
    }

    protected String[] sendToBank(String p_reqStr) throws Exception {
        //一：参数、对象定义
        String[] retStrArr = new String[]{"", ""};
        String tmpCharset = getCharset();
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
        TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);

        //二：组织报头
        p_reqStr = "00" + p_reqStr;
        byte[] tmpBytesBody = p_reqStr.getBytes(tmpCharset);
        String tmpHead = String.format("%010d", tmpBytesBody.length);
        byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

        //三：封装请求报文：【报头】、【报体】
        byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
        System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
        System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

        //四：发送报文
        WriteBankLogStep2(tmpHead + p_reqStr);
        TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesSend);
        //五：解析报文
        if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
            String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
            WriteBankLogStep3(tmpBkStr);
        }
        retStrArr[0] = tmpReceiver.connState;
        if (tmpReceiver.isCompleted) {
            retStrArr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength, tmpCharset);
        } else {
            retStrArr[1] = tmpReceiver.getConnMsg();
            WriteBankLogLn(retStrArr[1]);
        }

        return retStrArr;
    }

    protected String[] sendToBank(String p_reqStr,String transType,String commandCode) throws Exception {
        //一：参数、对象定义
        String[] retStrArr = new String[]{"", ""};
        String tmpCharset = getCharset();
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
        TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);

        //二：组织报头
        p_reqStr = "00" + p_reqStr;
        byte[] tmpBytesBody = p_reqStr.getBytes(tmpCharset);
        if (StringHelper.hasAnyChar(transType) && StringHelper.hasAnyChar(commandCode)) {
            this.detailSimulateForBank(bankFront.bankCode, transType, commandCode, p_reqStr, retStrArr);
            if (retStrArr[1].length() > 0) {
                WriteBankLogLn("银行返回的报文：" + retStrArr[1]);
                return retStrArr;
            }
        }
        String tmpHead = String.format("%010d", tmpBytesBody.length);
        byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

        //三：封装请求报文：【报头】、【报体】
        byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
        System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
        System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

        //四：发送报文
        WriteBankLogStep2(tmpHead + p_reqStr);
        TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesSend);
        //五：解析报文
        if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
            String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
            WriteBankLogStep3(tmpBkStr);
        }
        retStrArr[0] = tmpReceiver.connState;
        if (tmpReceiver.isCompleted) {
            retStrArr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength, tmpCharset);
        } else {
            retStrArr[1] = tmpReceiver.getConnMsg();
            WriteBankLogLn(retStrArr[1]);
        }

        return retStrArr;
    }

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    @Override
    public void getContentLength(TcpReceiver tcpReceiver) throws Exception {
        if (tcpReceiver.contentLength == -1) {
            if (tcpReceiver.readedLength >= 12) {
                String tmpHead = new String(tcpReceiver.recBytes, 0, 10, getCharset());
                tcpReceiver.contentLength = Integer.parseInt(tmpHead.trim()) - 2;
                tcpReceiver.contentStartIndex = 12;
            }
        }
    }
    public String getFileMD5(String filePath){
        FileInputStream fileInputStream = null;
        File file = new File(filePath);
        if(!file.exists()){
            return "";
        }
        try {
            MessageDigest MD5 = MessageDigest.getInstance("MD5");
            fileInputStream = new FileInputStream(filePath);
            byte[] buffer = new byte[8192];
            int length;
            while ((length = fileInputStream.read(buffer)) != -1) {
                MD5.update(buffer, 0, length);
            }
            return new String(Hex.encodeHex(MD5.digest()));
        } catch (Exception e) {
            e.printStackTrace();
            WriteBankLogLn(e);
            WriteBankLogLn("获取文件MD5失败");
            return "";
        } finally {
            try {
                if (fileInputStream != null){
                    fileInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //上送格式为json格式
    protected String[] sendToATS(String jsonData) throws Exception {
        String[] retStr = new String[]{"", ""};
        WriteBankLogLn("2.提交ATS的地址：" + FGBiz.dspCenter.dspSet.receiptPushServerUrl);


        //发送ATS
        WebRequest tmpRequest = new WebRequest(FGBiz.dspCenter.dspSet.receiptPushServerUrl);
        tmpRequest.setConnectTimeout(60000);
        tmpRequest.setRequestProperty("connection", "Close");
        tmpRequest.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        String charsetName = getCharset();
        WriteBankLogLn("3.推送给ATS的json数据" + jsonData);
        byte[] tmpWriteBytes = jsonData.getBytes(charsetName);
        retStr = tmpRequest.upload(tmpWriteBytes, charsetName);
        WriteBankLogLn("4.返回的数据" + retStr[1]);

        return retStr;
    }
}
